package png
{
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.utils.ByteArray;

	public class PngFileInfo
	{
		private var _propList:Array = [];
		private var _file:File;
		private var _hasPLTE:Boolean = false;
		private var _byteArray:ByteArray;
		
		public function PngFileInfo()
		{
		}
		
		public function open(file:File):void
		{
			if( file.exists==false || file == null)
				return;
			_file = file;
			
			_propList.length = 0;
			
			
			var fs:FileStream = new FileStream();			
			fs.open( file, FileMode.READ );
			var byteArray:ByteArray = new ByteArray();
			fs.readBytes(byteArray, 0, file.size );
			fs.close();
			
			_byteArray = byteArray;
			_byteArray.position = 0;
			readSignature( _byteArray );
			var moreChunk:Boolean = false;
			do{
				moreChunk = readChunck( _byteArray );
			}while(moreChunk);
			
		}
		
		public function openFromByteArray( byteArray:ByteArray ):void
		{
			_propList.length = 0;
			
			_byteArray = byteArray;
			_byteArray.position = 0;
			
			readSignature( _byteArray );
			var moreChunk:Boolean = false;
			do{
				moreChunk = readChunck( _byteArray );
			}while(moreChunk);
		}
		
		private function readSignature( fs:ByteArray ):void
		{
			var arr:Array = [];
			for(var i:int=0;i<8;i++)
				arr.push(fs.readUnsignedByte().toString(16).toUpperCase());
			addValue("signature", 8, arr.join(" "));
		}
		
		private function readChunck(fs:ByteArray ):Boolean
		{
			var dataLen:uint = fs.readUnsignedInt();
			var chunkType:String = fs.readUTFBytes(4);
			if(dataLen > 0){
				var data:ByteArray = new ByteArray();
				fs.readBytes( data, 0, dataLen );
			}
			var crc:uint =fs.readUnsignedInt(); 
			
			addValue("dataLength", 4, dataLen);
			addValue("chunkType", 4, chunkType);
			switch(chunkType)
			{
				case "IHDR":
					var ihdrChunk:IHDRChunk = new IHDRChunk;
					ihdrChunk.setData( data );
					addValue("IHDR.data", dataLen, ihdrChunk);
					break;
				case "PLTE":
					var plteChunk:PLTEChunk = new PLTEChunk;
					plteChunk.setData( data );
					addValue("PLTE.colors", dataLen, plteChunk);
					
					_hasPLTE = true;
					break;
				default:
					addValue(chunkType+".data", dataLen, "ByteArray");
					break;
			}
			addValue("CRC", 4, crc.toString(16).toUpperCase());
			
			if( chunkType == "IEND")
				return false;
			return true;
		}
		
		private function addValue( name:String, length:int, value:Object ):void
		{
			_propList.push({"name":name, "length":length, "value":value});	
		}
		
		public function get propList():Array
		{
			return _propList;
		}
		
		public function get file():File
		{
			return _file;
		}
		
		public function get hasPLTE():Boolean
		{
			return _hasPLTE;
		}
	}
}